#!/usr/bin/env python
# -*- coding: UTF-8 -*-

import shutil

import codecs
import os
import sys

execfile(os.path.join(sys.path[0], "framework.py"))

from oriolusdocker.storages.filestorage import FileStorage, FilePacketEntryReader
from orioluspith.packets.meta import Meta
from orioluspith.packets.packet import FilePacket, Packet, Status
from unittest import TestCase, TestLoader, TextTestRunner

class TestFileStorage(TestCase):
    def setUp(self):
        self.__empty_storage_path = os.path.abspath("./test_empty_storage")
        self.__test_storage_path2 = os.path.abspath("./test_storage2")
        self.__temp_dirs = [self.__empty_storage_path, self.__test_storage_path2]
        if not os.path.exists(self.__test_storage_path2):
            os.mkdir(self.__test_storage_path2)

    def tearDown(self):
        map(self.__clear_path, self.__temp_dirs)

    def __clear_path(self, path):
        if os.path.exists(path):
            shutil.rmtree(path)
           

    def test_absent_storage(self):
        FileStorage(self.__empty_storage_path)
        self.assertTrue(os.path.exists(self.__empty_storage_path))

    def test_existing_storage(self):
        self.assertTrue(os.path.exists(self.__test_storage_path2))
        FileStorage(self.__test_storage_path2)

    def test_add(self):
        test_packet = FilePacket("./testdata/testpackets/test_packet-1.2.3.4.zip.ori")
        storage = FileStorage(self.__test_storage_path2)
        storage.add(test_packet)
        expected_file_names = ("test_packet-1.2.3.4.ori.entry", "test_packet-1.2.3.4.install",
            "test_packet-1.2.3.4.postinstall", "test_packet-1.2.3.4.postremove",
            "test_packet-1.2.3.4.preinstall", "test_packet-1.2.3.4.preremove",
            "test_packet-1.2.3.4.remove")

        for expected_file_name in expected_file_names:
            self.assertTrue(os.path.exists(os.path.join(self.__test_storage_path2, expected_file_name)))

        expected_file_packet = Packet(Meta("test_packet", "1.2.3.4", "Test packet", [], [], []), status=Status.NEW)
        actual_file_packet = FilePacketEntryReader().read(os.path.join(self.__test_storage_path2, "test_packet-1.2.3.4.ori.entry"))
        self.__assertFilePacketEntryEqual(expected_file_packet, actual_file_packet)

        expected_install_script_content = ""
        actual_install_script_content = file(os.path.join(self.__test_storage_path2, "test_packet-1.2.3.4.install")).read()
        self.assertEqual(expected_install_script_content, actual_install_script_content)

        expected_postinstall_script_content = ""
        actual_postinstall_script_content = file(os.path.join(self.__test_storage_path2, "test_packet-1.2.3.4.postinstall")).read()
        self.assertEqual(expected_postinstall_script_content, actual_postinstall_script_content)

        expected_postremove_script_content = ""
        actual_postremove_script_content = file(os.path.join(self.__test_storage_path2, "test_packet-1.2.3.4.postremove")).read()
        self.assertEqual(expected_postremove_script_content, actual_postremove_script_content)

        expected_preremove_script_content = ""
        actual_preremove_script_content = file(os.path.join(self.__test_storage_path2, "test_packet-1.2.3.4.preremove")).read()
        self.assertEqual(expected_preremove_script_content, actual_preremove_script_content)

        expected_remove_script_content = ""
        actual_remove_script_content = file(os.path.join(self.__test_storage_path2, "test_packet-1.2.3.4.remove")).read()
        self.assertEqual(expected_remove_script_content, actual_remove_script_content)
                        
        expected_preinstall_script_content = "import os\r\n\r\nprint \"Test\""
        actual_preinstall_script_content = codecs.open(os.path.join(self.__test_storage_path2, "test_packet-1.2.3.4.preinstall"), encoding = "utf-8").read()
        self.assertEqual(expected_preinstall_script_content, actual_preinstall_script_content)        

    def test_remove(self):
        test_packet = FilePacket("./testdata/testpackets/test_packet-1.2.3.4.zip.ori")
        storage = FileStorage(self.__test_storage_path2)
        storage.add(test_packet)
        expected_file_names = ("test_packet-1.2.3.4.ori.entry", "test_packet-1.2.3.4.install",
            "test_packet-1.2.3.4.postinstall", "test_packet-1.2.3.4.postremove",
            "test_packet-1.2.3.4.preinstall", "test_packet-1.2.3.4.preremove",
            "test_packet-1.2.3.4.remove")

        for expected_file_name in expected_file_names:
            self.assertTrue(os.path.exists(os.path.join(self.__test_storage_path2, expected_file_name)))

        storage.remove("test_packet-1.2.3.4")

        for expected_file_name in expected_file_names:
            self.assertFalse(os.path.exists(os.path.join(self.__test_storage_path2, expected_file_name)))

    def test_entries(self):
        test_packet = FilePacket("./testdata/testpackets/test_packet-1.2.3.4.zip.ori")
        storage = FileStorage(self.__test_storage_path2)
        storage.add(test_packet)
        expected_file_names = ("test_packet-1.2.3.4.ori.entry", "test_packet-1.2.3.4.install",
            "test_packet-1.2.3.4.postinstall", "test_packet-1.2.3.4.postremove",
            "test_packet-1.2.3.4.preinstall", "test_packet-1.2.3.4.preremove",
            "test_packet-1.2.3.4.remove")
        
        actual_entries = storage.entries
        self.assertEqual(1, len(actual_entries))
        actual_packet = actual_entries[0]

        self.assertEqual(test_packet.name, actual_packet.name)
        self.assertEqual(test_packet.meta.version, actual_packet.meta.version)
        self.assertEqual(test_packet.meta.description, actual_packet.meta.description)
        self.assertEqual([], actual_packet.meta.conflicts)
        self.assertEqual([], actual_packet.meta.depends)
        self.assertEqual([], actual_packet.meta.replaces)
        self.assertEqual(6, len(actual_packet.scripts))
        self.assertTrue(actual_packet.scripts.has_key("install"))
        self.assertTrue("test_packet-1.2.3.4.install", actual_packet.scripts["install"].name)
        self.assertEqual(test_packet.status, actual_packet.status)

    def __assertFilePacketEntryEqual(self, expected, actual):
        self.assertEqual(type(expected), type(actual))
        self.assertEqual(expected.meta.name, actual.meta.name)
        self.assertEqual(expected.meta.version, actual.meta.version)
        self.assertEqual(expected.meta.description, actual.meta.description)
        self.assertEqual(expected.meta.conflicts, actual.meta.conflicts)
        self.assertEqual(expected.meta.replaces, actual.meta.replaces)
        self.assertEqual(expected.meta.depends, actual.meta.depends)
        self.assertEqual(expected.status, actual.status)

if __name__ == "__main__":
    suite = TestLoader().loadTestsFromTestCase(TestFileStorage)
    TextTestRunner(verbosity=2).run(suite)
